package com.hk.service.yingmi.impl;

import com.hk.commons.HqlFilter;
import com.hk.commons.StringHelper;
import com.hk.commons.entity.FundInfo_Yimi;
import com.hk.commons.utils.yingmi.YingmiApiUtils;
import com.hk.service.IFundInfo_Yimi;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * Created by Antinomy on 17/9/25.
 */
@Service
public class YingmiProductRepository {

    private Logger logger = LoggerFactory.getLogger(YingmiProductRepository.class);

    @Autowired
    private YingmiApiUtils utils;

    @Autowired
    private IFundInfo_Yimi fundInfoService;

    @Value("${yingmi.file.host}")
    private String host;

    @Value("${yingmi.data.file}")
    private String fileSave;

    public void storeYingmiLatestProduct() {
    /*
     * /file/yingmi_<商户号>_order_<YYYYMMDD>.txt
     */
        SimpleDateFormat sf = new SimpleDateFormat("YYYMMdd");
        String date = sf.format(System.currentTimeMillis());
        String path = "yingmi_fundinfo_" + date;
        Map<String, String> params = new HashMap<>();
        String fileName = path + ".txt";
        String fileStr = utils.fileGet("/data/latest/fundinfo", params, host);

        // 生成订单流文件
        Path filePath = Paths.get(fileSave + fileName);

        if (!Files.exists(Paths.get(fileSave + fileName))) {
            try {
                Files.write(filePath, fileStr.getBytes("UTF-8"));
                ExecutorService executor = Executors.newFixedThreadPool(1);
                Runnable task = () -> saveOrderInfo(fileName);
                executor.execute(task);
                executor.shutdown();
            } catch (IOException e) {
                logger.error("file:{} error:{}", fileName, e);
            }
        }
    }

    private void saveOrderInfo(String fileName) {
        logger.info("更新基金表");
        List<String> list;
        try {
            list = Files
                    .lines(Paths.get(fileSave + fileName))
                    .collect(Collectors.toList());

            String[] cols = null;

            HqlFilter countFilter = new HqlFilter();
            List<FundInfo_Yimi> allList = fundInfoService.findByFilter(countFilter);
            int count = allList.size();

            for (int i = 2; i < list.size(); i++) {
                cols = StringUtils.splitPreserveAllTokens(list.get(i), '|');
                FundInfo_Yimi f = new FundInfo_Yimi();
                String fundCode = cols[1];
                HqlFilter hqlFilter = new HqlFilter();
                hqlFilter.addEQFilter("fundCode", fundCode);
                List<FundInfo_Yimi> fundList = fundInfoService.findByFilter(hqlFilter);

                if (fundList.size() == 0) {
                    f.setId("" + (count + 1));
                    f = setValue(f, cols);
                    fundInfoService.add(f);
                    count++;
                    logger.info("新增记录,fundCode={}", fundCode);
                } else {// 更新
                    FundInfo_Yimi fundInfo_Yimi = fundList.get(0);
                    fundInfo_Yimi = setValue(fundInfo_Yimi, cols);
                    fundInfoService.update(fundInfo_Yimi);
                }
            }
        } catch (Exception e) {
            logger.error("fileName :{} saveOrderInfo fail : {}", fileName, e);
        }
        logger.info("基金文件信息处理完毕");
    }


    /**
     *  0 序号
     * */
    private FundInfo_Yimi setValue(FundInfo_Yimi fund, String[] cols) {

        // 1 基金代码
        fund.setFundCode(cols[1]);

        // 2 基金全称
        fund.setFundFullName(cols[2]);

        // 3 基金简称
        fund.setFundName(cols[3]);

        // 4 基金类型
        fund.setFundType(cols[4]);

        // 5 风险等级
        fund.setRiskLevel(Integer.parseInt(cols[5]));

        // 6 确认天数
        fund.setConfirmPace(getZeroWhenEmpty(cols[6]));

        // 7 赎回到账天数
        fund.setRefundPace(getZeroWhenEmpty(cols[7]));

        // 8 默认分红方式
        fund.setDefaultDividendMethod(getZeroWhenEmpty(cols[8]));

        // 9 币种
        fund.setCurrency(getZeroWhenEmpty(cols[9]));

        // 10 销售状态
        fund.setOnSale(getZeroWhenEmpty(cols[10]));

        // 11 收费类型
        fund.setShareTypeJArray(cols[11]);

        // 12 定投开通标志
        fund.setSupportPeriodic(getZeroWhenEmpty(cols[12]));

        // 13 转换开通标志
        fund.setSupportConvert(getZeroWhenEmpty(cols[13]));

        // 14 管理费率
        fund.setManagerRate(getNullWhenEmpty(cols[14]));

        // 15 托管费率
        fund.setTrusteeRate(getNullWhenEmpty(cols[15]));

        // 16 前端认购费率
        fund.setSubscribeRateJArray(cols[16]);

        // 17 前端申购费率
        fund.setAllotRateJArray(cols[17]);

        // 18 赎回费率
        fund.setRedeemRateJArray(cols[18]);

        // 19 个人首次认购最低金额
        fund.setMinIndividualSubscribeAmount(getNullWhenEmpty(cols[19]));

        // 20 个人追加认购最低金额
        fund.setMinIndividualAppendSubscribeAmount(getNullWhenEmpty(cols[20]));

        // 21 个人最高认购金额
        fund.setMaxIndividualSubscribeAmount(getNullWhenEmpty(cols[21]));

        // 22 个人首次申购最低金额
        fund.setMinIndividualAllotAmount(getNullWhenEmpty(cols[22]));

        // 23 个人追加申购最低金额
        fund.setMinIndividualAppendAllotAmount(getNullWhenEmpty(cols[23]));

        // 24 个人最高申购金额
        fund.setMaxIndividualAllotAmount(getNullWhenEmpty(cols[24]));

        // 25 个人定投申购最低金额
        fund.setMinIndividualPeriodicAmount(getNullWhenEmpty(cols[25]));

        // 26 个人持有最低份额
        fund.setMinIndividualHoldVol(getNullWhenEmpty(cols[26]));

        // 27 个人赎回最低份额
        fund.setMinIndividualRedeemVol(getNullWhenEmpty(cols[27]));

        // 28 个人转换最低份额
        fund.setMinIndividualConvertVol(getNullWhenEmpty(cols[28]));

        // 29 成立日期
        fund.setSetupDate(cols[29]);

        // 30 管理人
        fund.setFundCorp(cols[30]);

        // 31 托管人
        fund.setTrustee(cols[31]);

        // 32 基金经理
        fund.setFundManagerJArray(cols[32]);

        // 33 报告日期
        fund.setReportDate(cols[33]);

        // 34 资产规模
        if (StringHelper.isNotEmpty(cols[34])) {
            fund.setAssetAmount(new BigDecimal(cols[34]));
        } else {
            fund.setAssetAmount(new BigDecimal(0));
        }

        // 35 份额规模
        fund.setAssetVol(getNullWhenEmpty(cols[35]));

        // 36 十大重仓股
        fund.setStockPortfolioJArray(cols[36]);

        // 37 行业配置
        fund.setIndustryPortfolioJArray(cols[37]);

        // 38 资产配置
        fund.setAssetPortfolioJArray(cols[38]); //

        // 39 是否可修改分红方式
        fund.setAllowUpdateDividendMethod(getZeroWhenEmpty(cols[39]));

        // 40 销售服务费
        // 41 个人定投申购最高金额
        // 42 是否需要签订电子合同
        // 43 产品类型
        // 44 申购开通标志
        // 45 认购开通标志
        // 46 购买开通标志
        // 47 非标准赎回费
        // 48 五档风险等级
        // 49 暂停大额限购数据
        // 50 协会标准基金五级风险

        return fund;
    }

    private BigDecimal getNullWhenEmpty(String head) {
        return !StringUtils.isEmpty(head) ? new BigDecimal(head) : null;
    }

    private int getZeroWhenEmpty(String head) {
        return !StringUtils.isEmpty(head) ? Integer.parseInt(head) : 0;
    }
}
